﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Model
{
    /// <summary>
    /// 数据片
    /// </summary>
    public class DataSpan<T>
    {
        private T[] _buffer = null;
        /// <summary>
        /// 数组数据
        /// </summary>
        public T[] Buffer
        {
            get
            {
                return this._buffer;
            }
        }

        private IEnumerable<T> _items = null;
        /// <summary>
        /// 集合数据
        /// </summary>
        public IEnumerable<T> Items
        {
            get
            {
                return this._items;
            }
        }


        private int _offset;
        /// <summary>
        /// 数据起始偏移位置,小于等于0从头开始
        /// </summary>
        public int Offset
        {
            get
            {
                return this._offset;
            }
        }

        private int _length;
        /// <summary>
        /// 数据长度，小于0到结尾
        /// </summary>
        public int Length
        {
            get
            {
                return this._length;
            }
        }

        /// <summary>
        /// 获取或设置与缓存数据关联的用户定义的数据
        /// </summary>
        public object Tag { get; set; }





        /// <summary>
        /// 构造函数
        /// </summary>
        public DataSpan()
        {

        }

        /// <summary>
        /// 构造函数-数组数据片
        /// </summary>
        /// <param name="buffer">内存数组buffer数据</param>
        /// <param name="startIndex">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public DataSpan(T[] buffer, int startIndex = -1, int length = -1)
        {
            this.Update(buffer, startIndex, length);
        }

        /// <summary>
        /// 构造函数-集合数据片
        /// </summary>
        /// <param name="items">内存数组buffer数据</param>
        /// <param name="startIndex">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public DataSpan(IEnumerable<T> items, int startIndex = -1, int length = -1)
        {
            this.Update(items, startIndex, length);
        }



        /// <summary>
        /// 更新数据片
        /// </summary>
        /// <param name="startIndex">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public void Update(int startIndex = -1, int length = -1)
        {
            T[] buffer = this._buffer;
            if (startIndex < 0)
            {
                startIndex = 0;
            }
            else if (startIndex >= buffer.Length)
            {
                throw new ArgumentOutOfRangeException($"数据起始偏移位置\"{startIndex}\"无效,超出范围");
            }

            if (length < 0)
            {
                length = buffer.Length - startIndex;
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException($"长度值\"{length}\"无效,超出范围,不能小于0");
            }

            this._offset = startIndex;
            this._length = length;
        }


        /// <summary>
        /// 更新数据片
        /// </summary>
        /// <param name="buffer">内存数组buffer数据</param>
        /// <param name="startIndex">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public void Update(T[] buffer, int startIndex = -1, int length = -1)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (startIndex < 0)
            {
                startIndex = 0;
            }
            else if (startIndex >= buffer.Length)
            {
                throw new ArgumentOutOfRangeException($"数据起始偏移位置\"{startIndex}\"无效,超出范围");
            }

            if (length < 0)
            {
                length = buffer.Length - startIndex;
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException($"长度值\"{length}\"无效,超出范围,不能小于0");
            }

            this._buffer = buffer;
            this._offset = startIndex;
            this._length = length;
        }

        /// <summary>
        /// 更新数据片
        /// </summary>
        /// <param name="items">内存数组buffer数据</param>
        /// <param name="startIndex">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public void Update(IEnumerable<T> items, int startIndex = -1, int length = -1)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            if (startIndex < 0)
            {
                startIndex = 0;
            }
            else if (startIndex >= items.Count())
            {
                throw new ArgumentOutOfRangeException($"数据起始偏移位置\"{startIndex}\"无效,超出范围");
            }

            if (length < 0)
            {
                length = items.Count() - startIndex;
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException($"长度值\"{length}\"无效,超出范围,不能小于0");
            }

            this._items = items;
            this._offset = startIndex;
            this._length = length;
        }

    }


}
